package Controllers

import (
	"fmt"
	_ "log"
	"sync"
	"yz-go/Common"
	"yz-go/Models"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

var lock sync.RWMutex

func LockQuery(c *gin.Context) {

	// 启动日志
	Logger, err := NewLogger()
	if err != nil {
		// 初始化失败
		panic(err)
	}

	su := Logger.Sugar()
	defer su.Sync()

	if err != nil {
		// log.Fatal("无法连接到数据库：", err)
		su.Info("无法连接到数据库：",
			zap.Error(err),
		)
	}

	// 启动多个查询任务
	numQueries := 3
	var wg sync.WaitGroup
	wg.Add(numQueries)

	for i := 0; i < numQueries; i++ {
		go executeQuery(i+1, &wg, Logger)
	}

	// 等待查询任务完成
	wg.Wait()

	Common.SuccessResponse(c, Common.SUCCESS, "所有查询任务已完成")
}

type Job struct {
	ID                 uint
	PositionCustomName string
	Release            string
}

func executeQuery(queryID int, wg *sync.WaitGroup, Logger *zap.Logger) {
	// -------------------------------------- 锁 --------------------------------------
	// 加读锁
	lock.RLock()
	defer lock.RUnlock()

	// 如果下面有对数据库进行写/更新操作的时候 这里的锁 就需要改成写锁，而不能是读锁
	// 只要这个方法里有写的操作就必须是读锁，哪怕在这个方法里面 把写的操作独立出去一个新的方法
	// lock.Lock()
	// defer lock.Unlock()

	// 启动日志 ------------- 接收了上面传入的日志实例 这里无需在实例化，*** 传入的实例必须是原始的类型 如： *zap.Logger
	// Logger, errLog := NewLogger()
	// if errLog != nil {
	// 	// 初始化失败
	// 	panic(errLog)
	// }
	su := Logger.Sugar()
	defer su.Sync()

	// -------------------------------------- 锁 --------------------------------------

	// 执行数据库查询任务  【另一种查询方式】
	var job []Job
	query := fmt.Sprintf("SELECT id,position_custom_name,`release` FROM recruit_job WHERE id = %d", queryID)
	// fmt.Println(query)
	err := Models.DB.Raw(query).Scan(&job).Error

	// 查询数量 count(1) / count(*)
	var nm int64
	Models.DB.Raw("SELECT count(1) FROM recruit_job").Scan(&nm)

	// 原生执行sql 【exec 只适用于 更新 删除。 raw用于查找】
	// Models.DB.Exec("delete FROM recruit_job WHERE id = ?", 2)	// 直接删除
	// Models.DB.Exec("update recruit_job set name = ? recruit_job WHERE id = %d","name",2)	// 更新

	if err != nil {
		// log.Printf("查询任务 %d 执行失败: %v\n", queryID, err)	最原始的方法
		su.Info("查询任务 %d 执行失败: %v\n", queryID,
			zap.Error(err),
		)
	} else {
		// 遍历查询结果
		for _, j := range job {
			fmt.Printf("ID: %d, Name: %s, Age: %s\n", j.ID, j.PositionCustomName, j.Release)
		}
	}

	/*	查询结果：
		ID: 3, Name: 网页设计, Age: 都琭
		ID: 1, Name: UI设计师, Age: 辟晓兰
		ID: 2, Name: 美工, Age: 益天逸
	*/
	wg.Done()
}
